<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	class FilterTest extends AbstractTekunaTestCase {


		public function testAlphanumericCharsFilter() {

			// get filter instance
			$objFilter = new AlphanumericCharsFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
			$this -> assertIdentical($objFilter -> filter('äöüÄÖÜß? <>|,.-;:_#\'+*"![]{}&%$§()'), '');
		}


		public function testBooleanFilter() {

			// get filter instance
			$objFilter = new BooleanFilter();

			// test TRUE filter results
			$this -> assertIdentical($objFilter -> filter(TRUE), TRUE);
			$this -> assertIdentical($objFilter -> filter('true'), TRUE);
			$this -> assertIdentical($objFilter -> filter('TRUE'), TRUE);
			$this -> assertIdentical($objFilter -> filter('1'), TRUE);
			$this -> assertIdentical($objFilter -> filter(1), TRUE);
			$this -> assertIdentical($objFilter -> filter('asdf'), TRUE);

			// test FALSE filter results
			$this -> assertIdentical($objFilter -> filter(FALSE), FALSE);
			$this -> assertIdentical($objFilter -> filter('false'), FALSE);
			$this -> assertIdentical($objFilter -> filter('FALSE'), FALSE);
			$this -> assertIdentical($objFilter -> filter('0'), FALSE);
			$this -> assertIdentical($objFilter -> filter(0), FALSE);
			$this -> assertIdentical($objFilter -> filter(''), FALSE);
		}


		public function testEmptyFilter() {

			// get filter instance
			$objFilter = new EmptyFilter();

			// test filter
			$this -> assertIdentical(NULL, NULL);
			$this -> assertIdentical(TRUE, TRUE);
			$this -> assertIdentical(1, 1);
			$this -> assertIdentical('asdf', 'asdf');
			$this -> assertIdentical(array(array(), array('array')), array(array(), array('array')));
			$this -> assertIdentical(new stdClass(), new stdClass());
		}


		public function testEntityDecodeFilter() {

			// get filter instance
			$objFilter = new EntityDecodeFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('&#33;'), '!');
			$this -> assertIdentical($objFilter -> filter('&#x21;'), '!');
			$this -> assertIdentical($objFilter -> filter('&auml;'), utf8_decode('ä'));
			$this -> assertIdentical($objFilter -> filter('&amp;'), '&');
			$this -> assertIdentical($objFilter -> filter('&#39;'), '\'');
			$this -> assertIdentical($objFilter -> filter('&quot;'), '"');
		}


		public function testFilterChain() {

			// test empty construction
			try {

				$objFilterChain = new FilterChain();

				$this -> fail("The construction of an empty FilterChain must result in an OutOfRangeException.");
			}
			catch (OutOfRangeException $e) {

				$this -> pass();
			}


			// test wrong parameter construction
			try {

				$objFilterChain = new FilterChain('test', 2, FALSE);

				$this -> fail("If the FilterChain is constructed with parameters that are not of type TekunaFilter, a InvalidArgumentException must be thrown.");
			}
			catch (InvalidArgumentException $e) {

				$this -> pass();
			}


			// test chain filtering
			$objFilterChain = new FilterChain(new EntityDecodeFilter(), new BooleanFilter());

			// test values
			$this -> assertIdentical($objFilterChain -> filter('&#48;'), FALSE);
		}


		public function testFloatFilter() {

			// get filter instance
			$objFilter = new FloatFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('1.1'), 1.1);
			$this -> assertIdentical($objFilter -> filter('2,2'), 2.2);
		}


		public function testIntegerFilter() {

			// get filter instance
			$objFilter = new IntegerFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('1'), 1);
			$this -> assertIdentical($objFilter -> filter('2.9'), 2);
			$this -> assertIdentical($objFilter -> filter('-3w'), -3);
		}


		public function testLengthFilter() {

			try {

				// try no parameter instantiation
				$objFilter = new LengthFilter();

				// a raised PHPWarningException should stopped the try block
				$this -> fail();
			}
			catch (PHPWarningException $e) {

				// everything OK
				$this -> pass();
			}


			// get filter instance
			$objFilter = new LengthFilter(3);

			// test filter
			$this -> assertIdentical($objFilter -> filter('abcdefg'), 'abc');
		}


		public function testNoHTMLFilter() {

			// get filter instance
			$objFilter = new NoHTMLFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), 'text');
			$this -> assertIdentical($objFilter -> filter('text <b>bold</b> word'), 'text bold word');
			$this -> assertIdentical($objFilter -> filter('text <b>bold</b> word <script'), 'text bold word ');
			$this -> assertIdentical($objFilter -> filter('text <b>bold</b> word <script type=">foo'), 'text bold word ');
		}


		public function testNoScriptFilter() {

			// get filter instance
			$objFilter = new NoScriptFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), 'text');
			$this -> assertIdentical($objFilter -> filter('text <b>bold</b> word'), 'text <b>bold</b> word');
			$this -> assertIdentical($objFilter -> filter('text <script>/* regular script */</script> word'), 'text  word');
			$this -> assertIdentical($objFilter -> filter('text <script src="http://badhost.com/xss.js" </script word'), 'text ');
			$this -> assertIdentical($objFilter -> filter('text <a href="jav asc    ript:xss();"> word'), 'text <a href="xss();"> word');
			$this -> assertIdentical($objFilter -> filter('text <div onClICk="xss();">foo</div>'), 'text <div >foo</div>');
			$this -> assertIdentical($objFilter -> filter('text <a href="" onclick=alert(\'xss\');'), 'text ');
			$this -> assertIdentical($objFilter -> filter('text <style> body { -moz-binding: url("http://badhost.com/badscript.pl"); } </style>'), 'text <style> body {  } </style>');
			$this -> assertIdentical($objFilter -> filter('text <style> body { top:expression(alert(\'xss\')); } </style>'), 'text <style> body { top:; } </style>');
			$this -> assertIdentical($objFilter -> filter('text <div style="-moz-binding     : url("http://badhost.com/badscript.pl"); color:red; ">between</div> end'), 'text <div style=" color:red; ">between</div> end');
			$this -> assertIdentical($objFilter -> filter('text <p style="top:expression(alert(\'xss\'));">XSS Test</p> end'), 'text <p style="top:;">XSS Test</p> end');
		}


		public function testNoSpecialCharsFilter() {

			// get filter instance
			$objFilter = new NoSpecialCharsFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), 'text');
			$this -> assertIdentical($objFilter -> filter('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.:;!-_ '), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.:;!-_ ');
			$this -> assertIdentical($objFilter -> filter('äöüÄÖÜß?@<>|#*\'"~'), '');
		}


		public function testTekunaActionFilter() {

			// get filter instance
			$objFilter = new TekunaActionFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), '/text');
			$this -> assertIdentical($objFilter -> filter('/text'), '/text');
			$this -> assertIdentical($objFilter -> filter(''), '/');
			$this -> assertIdentical($objFilter -> filter("()[]{}\$§\n\r\t"), '/');
		}


		public function testPHPInternalFilter() {

			try {

				// get filter instance
				$objFilter = new PHPInternalFilter();

				// a raised PHPWarningException should stopped the try block
				$this -> fail();
			}
			catch (PHPWarningException $e) {

				// everything OK
				$this -> pass();
			}


			// test all PHP filters
			foreach (filter_list() as $iFilter => $sFilter) {

				// universal test string
				$sTestString = 'abcdefgABCDEFG012345;:_,.-+\'"@<>|µ^°´`äöüß?§$%&/()=[]{}'."\n\t\r";

				// test filter implementation and PHP filter in parallel
				$objFilter = new PHPInternalFilter($iFilter);

				// the same results must occur
				$this -> assertIdentical($objFilter -> filter($sTestString), filter_var($sTestString, $iFilter));
			}
		}


		public function testPrintableCharsFilter() {

			// get filter instance
			$objFilter = new PrintableCharsFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter("text "), "text ");
			$this -> assertIdentical($objFilter -> filter(chr(0)), "");
			$this -> assertIdentical($objFilter -> filter(chr(1)), "");
			$this -> assertIdentical($objFilter -> filter(chr(2)), "");
			$this -> assertIdentical($objFilter -> filter(chr(3)), "");
			$this -> assertIdentical($objFilter -> filter(chr(4)), "");
			$this -> assertIdentical($objFilter -> filter(chr(5)), "");
			$this -> assertIdentical($objFilter -> filter(chr(6)), "");
			$this -> assertIdentical($objFilter -> filter(chr(7)), "");
			$this -> assertIdentical($objFilter -> filter(chr(8)), "");
			$this -> assertIdentical($objFilter -> filter(chr(9)), "\t");
			$this -> assertIdentical($objFilter -> filter(chr(10)), "\n");
			$this -> assertIdentical($objFilter -> filter(chr(11)), "");
			$this -> assertIdentical($objFilter -> filter(chr(12)), "");
			$this -> assertIdentical($objFilter -> filter(chr(13)), "");
			$this -> assertIdentical($objFilter -> filter(chr(14)), "");
			$this -> assertIdentical($objFilter -> filter(chr(15)), "");
			$this -> assertIdentical($objFilter -> filter(chr(16)), "");
			$this -> assertIdentical($objFilter -> filter(chr(17)), "");
			$this -> assertIdentical($objFilter -> filter(chr(18)), "");
			$this -> assertIdentical($objFilter -> filter(chr(19)), "");
			$this -> assertIdentical($objFilter -> filter(chr(20)), "");
			$this -> assertIdentical($objFilter -> filter(chr(21)), "");
			$this -> assertIdentical($objFilter -> filter(chr(22)), "");
			$this -> assertIdentical($objFilter -> filter(chr(23)), "");
			$this -> assertIdentical($objFilter -> filter(chr(24)), "");
			$this -> assertIdentical($objFilter -> filter(chr(25)), "");
			$this -> assertIdentical($objFilter -> filter(chr(26)), "");
			$this -> assertIdentical($objFilter -> filter(chr(27)), "");
			$this -> assertIdentical($objFilter -> filter(chr(28)), "");
			$this -> assertIdentical($objFilter -> filter(chr(29)), "");
			$this -> assertIdentical($objFilter -> filter(chr(30)), "");
			$this -> assertIdentical($objFilter -> filter(chr(31)), "");
			$this -> assertIdentical($objFilter -> filter(chr(32)), " ");
		}


		public function testSQLFilter() {

			// get filter instance
			$objFilter = new SQLFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), 'text');
			$this -> assertIdentical($objFilter -> filter('te\'xt'), 'te\\\'xt');
			$this -> assertIdentical($objFilter -> filter('te"xt'), 'te\\"xt');
			$this -> assertIdentical($objFilter -> filter('te\\xt'), 'te\\\\xt');
			$this -> assertIdentical($objFilter -> filter('te\000xt'), 'te\\\000xt');

			$this -> assertIdentical($objFilter -> filter("\n"), "\\\n");
			$this -> assertIdentical($objFilter -> filter("\r"), "\\\r");
			$this -> assertIdentical($objFilter -> filter("\t"), "\\\t");
			$this -> assertIdentical($objFilter -> filter("\x1a"), "\\\x1a");
		}


		public function testTrimFilter() {

			// get filter instance
			$objFilter = new TrimFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('  a b  '), 'a b');
			$this -> assertIdentical($objFilter -> filter("\r\n  \ttext\r\ntext\n\r  "), "text\r\ntext");
		}


		public function testUnixLineDelimitersFilter() {

			// get filter instance
			$objFilter = new UnixLineDelimitersFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter(""), "");
			$this -> assertIdentical($objFilter -> filter("foo\nbar"), "foo\nbar");
			$this -> assertIdentical($objFilter -> filter("foo\n\nbar"), "foo\n\nbar");
			$this -> assertIdentical($objFilter -> filter("foo\r\nbar"), "foo\nbar");
			$this -> assertIdentical($objFilter -> filter("foo\rbar"), "foo\nbar");
			$this -> assertIdentical($objFilter -> filter("foo\r\rbar"), "foo\n\nbar");
			$this -> assertIdentical($objFilter -> filter("foo\n\rbar"), "foo\n\nbar");
		}


		public function testURLCharsFilter() {

			// get filter instance
			$objFilter = new URLCharsFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('http://user:passwd@my.good.com/url/page.html#anchor?param=value&param2=value%202!.,:;_-'), 'http://user:passwd@my.good.com/url/page.html#anchor?param=value&param2=value%202!.,:;_-');
			$this -> assertIdentical($objFilter -> filter("()[]{}\$§\n\r\t"), '');
		}


		public function testXMLSpecialCharsFilter() {

			// get filter instance
			$objFilter = new XMLSpecialCharsFilter();

			// test filter
			$this -> assertIdentical($objFilter -> filter('text'), 'text');
			$this -> assertIdentical($objFilter -> filter('&'), '&#38;');
			$this -> assertIdentical($objFilter -> filter('<'), '&#60;');
			$this -> assertIdentical($objFilter -> filter('>'), '&#62;');
			$this -> assertIdentical($objFilter -> filter('"'), '&#34;');
			$this -> assertIdentical($objFilter -> filter('\''), '&#39;');
			$this -> assertIdentical($objFilter -> filter('[]{}()%§!#'), '[]{}()%§!#');
		}


		public function testEmptyFileFilter() {

			// get filter instance
			$objFilter = new EmptyFileFilter();

			// create testing PostFile instance
			$objPostFile = new PostFile('testFile', array('name' => '', 'tmp_name' => '', 'size' => '', 'type' => '', 'error' => ''));

			// test the filter (that essentially does nothing)
			$this -> assertReference($objFilter -> filter($objPostFile), $objPostFile);
		}
	}



